package co.fitstart.admin.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.utils.DateFormatUtils;

import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.round.CourseRoundResult;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;
import co.fitstart.entity.user.bwh.BwhRecord;
import co.fitstart.entity.user.inbody.InbodyRecord;

@Repository("courseDaoSupport")
public class CourseDaoSupport {
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dynamic
    private CoachDao coachDao;
    
    @Dynamic
    private CourseScheduleDao courseScheduleDao;
    
    @Dynamic
    private InbodyRecordDao inbodyRecordDao;
    
    @Dynamic
    private CourseRoundResultDao courseRoundResultDao;
    
    /**
     * 
     * @param site
     * @param coach
     * @param beginDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<CourseSchedule> listCourseSchedule(Site site, Principal coach, Date beginDate, Date endDate) {
        
        String sentence = "FROM CourseSchedule courseSchedule WHERE courseSchedule.disabled = false AND courseSchedule.coach IS NOT NULL AND courseSchedule.coach.disabled = false AND courseSchedule.occurDate >= :beginDate AND courseSchedule.occurDate <= :endDate";
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("beginDate", beginDate);
        parameters.put("endDate", endDate);
        
        if(coach != null) {
            parameters.put("coach", coach);
            sentence = sentence + " AND courseSchedule.coach = :coach";
        }
        
        if(site != null && coach == null) {
            List<Long> coachIds = coachDao.coacheIds(site.getManager());
            if(CollectionUtils.isNotEmpty(coachIds)) {
                sentence = sentence + " AND courseSchedule.coach.id in (:coachIds)";
                parameters.put("coachIds", coachIds);
            }else {
                return new ArrayList<CourseSchedule>();
            }
        }
        
        sentence = sentence + " ORDER BY occurHour";
        
        return genericDaoSupport.searchForList(sentence, parameters);
    }
    
    /**
     * 
     * @param sites
     * @param coach
     * @param beginDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<CourseSchedule> listCourseSchedule(List<Site> sites, Principal coach, Date beginDate, Date endDate) {
        
        String sentence = "FROM CourseSchedule courseSchedule WHERE courseSchedule.disabled = false AND courseSchedule.coach IS NOT NULL AND courseSchedule.coach.disabled = false AND courseSchedule.occurDate >= :beginDate AND courseSchedule.occurDate <= :endDate";
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("beginDate", beginDate);
        parameters.put("endDate", endDate);
        
        if(coach != null) {
            parameters.put("coach", coach);
            sentence = sentence + " AND courseSchedule.coach = :coach";
        }
        
        List<Long> coachIds = coachDao.coacheIds(sites);
        if(CollectionUtils.isNotEmpty(coachIds)) {
            sentence = sentence + " AND courseSchedule.coach.id in (:coachIds)";
            parameters.put("coachIds", coachIds);
        }else {
            return new ArrayList<CourseSchedule>();
        }
        
        sentence = sentence + " ORDER BY occurHour";
        
        return genericDaoSupport.searchForList(sentence, parameters);
    }
    
    /**
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Long> getYearCourseId() {
        return genericDaoSupport.searchForList("SELECT id FROM Course WHERE year = true");
    }

    /**
     * 记录初始与最近三围和inbody
     * @param courseRound
     */
    public void recordCourseRoundResult(CourseRound courseRound) {
        if(!courseRound.getCourse().isExperience()) {
            List<CourseSchedule> courseSchedules = courseScheduleDao.listCourseSchedule(courseRound, new ScheduleStatus[]{ScheduleStatus.FINISH});
            
            if(!courseSchedules.isEmpty()) {
                Date begin = courseSchedules.get(0).getOccurDate();
                Date end = courseSchedules.get(courseSchedules.size() - 1).getOccurDate();
                
                List<BwhRecord> bwhRecords = inbodyRecordDao.listBwhRecord(courseRound.getStudent().getUser(), DateFormatUtils.format(begin, "yyyy-MM-dd") + " 00:00:00", DateFormatUtils.format(end, "yyyy-MM-dd") + " 23:59:59");
                List<InbodyRecord> inbodyRecords = inbodyRecordDao.listInbodyRecord(courseRound.getStudent().getUser(), DateFormatUtils.format(begin, "yyyy-MM-dd") + " 00:00:00", DateFormatUtils.format(end, "yyyy-MM-dd") + " 23:59:59");
                
                if(!bwhRecords.isEmpty() || !inbodyRecords.isEmpty()) {
                    BwhRecord previousBwh = null;
                    BwhRecord laterBwh = null;
                    InbodyRecord previousInbody = null;
                    InbodyRecord laterInbody = null;
                    
                    if(!bwhRecords.isEmpty()) {
                        previousBwh = bwhRecords.get(bwhRecords.size() - 1);
                        laterBwh = bwhRecords.get(0);
                    }
                    
                    if(!inbodyRecords.isEmpty()) {
                        previousInbody = inbodyRecords.get(inbodyRecords.size() - 1);
                        laterInbody = inbodyRecords.get(0);
                    }
                    
                    CourseRoundResult result = courseRoundResultDao.load(courseRound);
                    if(result == null) {
                        result = new CourseRoundResult(courseRound, previousBwh, laterBwh, previousInbody, laterInbody);
                        genericDaoSupport.save(result);
                    } else {
                        genericDaoSupport.update(result.edit(previousBwh, laterBwh).edit(previousInbody, laterInbody));
                    }
                }
            }
        }
    }
}
